package com.gitee.qdbp.general.thirdpart.api.trade.service;

import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.general.thirdpart.api.alipay.model.AlipayPayee;
import com.gitee.qdbp.general.thirdpart.api.trade.model.OrderData;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PaidNotify;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PaidResponse;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PrepayData;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PrepayParams;
import com.gitee.qdbp.general.thirdpart.api.trade.model.PrepayResponse;
import com.gitee.qdbp.general.thirdpart.api.wechat.model.WechatPayee;
import com.gitee.qdbp.general.trade.enums.PaySource;

/**
 * 支付业务处理
 *
 * @author zhaohuihua
 * @version 171020
 */
public interface IPaymentBaseService {

    /** 获取收款人信息(支付前) **/
    default WechatPayee getWechatPayee(PrepayData data, PaySource paySource, WechatPayee defaults) throws ServiceException {
        return defaults;
    }

    /** 获取收款人信息(支付后) **/
    default WechatPayee getWechatPayee(OrderData data, PaidNotify notify, WechatPayee defaults)
            throws ServiceException {
        return defaults;
    }

    /** 获取收款人信息(支付前) **/
    default AlipayPayee getAlipayPayee(PrepayData data, PaySource paySource, AlipayPayee defaults) throws ServiceException {
        return defaults;
    }

    /** 获取收款人信息(支付后) **/
    default AlipayPayee getAlipayPayee(OrderData data, PaidNotify notify, AlipayPayee defaults)
            throws ServiceException {
        return defaults;
    }

    /** 生成付款单编号 **/
    String generatePaymentId(PrepayData data) throws ServiceException;

    /**
     * 检查订单, 检查支付状态, ...<br>
     * 返回PrepayData: totalAmount+, orderTitle+, orderContent, createTime, expireTime, orderId, paymentId<br>
     * 带+的参数为必填; 返回的orderId可以与入参中的orderId不相同; paymentId在首次支付时=null, 第二次开始返回之前的预付单编号;
     * 
     * @param params 付款参数
     * @return 订单信息
     * @throws ServiceException
     */
    PrepayData onPrepayCheckOrder(PrepayParams params) throws ServiceException;

    /**
     * 检查库存, ...
     * 
     * @param data 订单信息
     * @throws ServiceException
     */
    default void onPrepayCheckBusiness(PrepayData data) throws ServiceException {
    }

    /**
     * 创建预付单成功, 修改付款状态为支付中, ...<br>
     * 事务: Propagation.REQUIRED<br>
     * 
     * @param data 付款数据
     * @param response 预付响应信息
     * @throws ServiceException
     */
    default void onPrepayHandleOrder(PrepayData data, PrepayResponse response) throws ServiceException {
    }

    /**
     * 创建预付单成功, 锁定库存, ...<br>
     * 事务: Propagation.REQUIRED<br>
     * 
     * @param data 付款数据
     * @param response 预付响应信息
     * @throws ServiceException
     */
    default void onPrepayHandleBusiness(PrepayData data, PrepayResponse response) throws ServiceException {
    }

    /**
     * 创建预付单失败
     * 
     * @param data 付款数据
     * @param response 响应信息
     * @throws ServiceException
     */
    default void onPrepayHandleError(PrepayData data, PrepayResponse response) throws ServiceException {
    }

    /**
     * 支付成功时查询订单信息<br>
     * 订单查不到应抛出异常, 但不判断订单状态<br>
     * 返回OrderData: orderId为必填参数
     * 
     * @param notify 支付回调参数
     * @return 订单信息
     */
    OrderData onPaidQueryOrder(PaidNotify notify) throws ServiceException;

    /**
     * 支付成功, 修改付款状态, ...<br>
     * 事务: Propagation.REQUIRES_NEW<br>
     * <pre>
        // 1.判断该状态是否已处理
        if (response.getTradeState() == TradeState.TRADE_SUCCESS) { // 支付成功
            // 2.判断totalAmount与订单信息是否相符
            // 3.修改付款状态为支付成功
            // 4.修改订单状态为支付成功
        } else if (response.getTradeState() == TradeState.TRADE_PAY_FAIL) { // 交易失败
            // 2.修改付款状态为支付失败
        } else if (response.getTradeState() == TradeState.TRADE_CLOSED) { // 交易关闭
            // 2.修改付款状态为支付失败
            // 订单关闭不能依赖第三方的回调, 而应该由定时任务来控制
        } else {
            // ...
        }
     * </pre>
     * 
     * @param data 订单数据
     * @param notify 支付通知参数
     * @param response 支付响应信息
     * @return 是否成功, 返回true才会调用onPaidHandleBusiness
     * @throws ServiceException
     */
    default boolean onPaidHandleOrder(OrderData data, PaidNotify notify, PaidResponse response) throws ServiceException {
        return false;
    }

    /**
     * 核减库存/自动发货, ...<br>
     * 事务: Propagation.REQUIRES_NEW<br>
     * 
     * @param data 订单数据
     * @param notify 支付通知参数
     * @param response 支付响应信息
     * @throws ServiceException
     */
    default void onPaidHandleBusiness(OrderData data, PaidNotify notify, PaidResponse response)
            throws ServiceException {
    }
}
